Package com.toc.jndp

Source Code of com.toc.jndp.JNDService$SocketAcceptHandler

/*
* @(#) JNDService.java 1.0 27/06/2010
* Package: com.toc.jndp
*
* Copyright 2010 TOC, Studio. All rights reserved.
*/
package com.toc.jndp;

import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.rmi.MarshalledObject;
import java.rmi.Remote;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UnicastRemoteObject;
import java.util.Properties;

import javax.net.ServerSocketFactory;

import com.toc.jndp.service.Naming;
import com.toc.jndp.service.NamingFactory;
import com.toc.lib.ExceptionHelper;
import com.toc.lib.GenericException;
import com.toc.lib.ResourceLoader;
import com.toc.lib.net.DefaultServerSocketFactory;

/**
* Title: TOC JNDI Provider Service Helper
* <p><b>Description: </b>
* <p>This class is help you to start the TOC JNDI Provider Service.
* <p><b>Instruction of TOC JNDP Service:</b>
* <ul>TOC JNDI Provider is construct on 1.6 JDK. You can use it as a stand-alone or integrate it with your own java program, it use RMI Java Technology as the implementation of the JNDI SPI and you can choose below technology as server storage implementation.
* <li>0-Runtime
* </ul>
* <ol>To start a stand-alone TOC JNDP instance, you can follow below step:
* <li>Install Java 1.6 or later JVM and get mandatory library (refer to <a href="#dependence">Dependence</a>)
* <li>Create a folder as the home folder of JNDP. Copy the library into home folder, create the JNDI properties file in the folder name as 'jndp.properties'.
* <li>Configure the properties in JNDI properties file. The configurable item can refer to <a href="#configurable">Configurable Item</a>.
* <li>Create a Shell Script(UNIX/Linux) or Command Script(Windows), add below java command:
* <pre>java -classpath {JNDP_HOME}\tocjndp.jar;{JNDP_HOME}\toclib.jar {@link com.toc.jndp.StandAloneJNDServiceStarter}</pre>
* <li>Execute the Shell Script/Command Script to start the JNDP Service.
* </ol>
* <ol>
* To integration TOC JNDP with your own program, you can follow below step:
* <li>Your program required build base on Java 1.6 or above.
* <li>Add mandatory library of JNDP Service to you classpath.(refer to <a href="#dependence">Dependence</a>)
* <li>Create the JNDI properties file in your classpath name as 'jndp.properties'.
* <li>Configure the properties in JNDI properties file. The configurable item can refer to <a href="#configurable">Configurable Item</a>.
* <li>Use below code to start the service:
* <pre>
* JNDService service = new JNDService();
* service.start();
* </pre>
* </ol>
* <blockquote>
* <b><a name="configurable" />Configurable Items (jndp.properties)</b>
* <br>All the items below are optional.
* <table border=0 cellspacing=3 cellpadding=0 summary="Examples of date and time patterns interpreted in the U.S. locale">
*   <tr bgcolor="#ccccff">
*     <th align=left>Name
*     <th align=left>Description
*     <th align=left>Properties
*     <th align=left>Code
*     <th align=left>Default
*   <tr>
*     <td>Binding Address
*     <td>The net address bind to the service
*     <td>com.toc.jndp.service.bindaddress
*     <td>KEY_JNDP_BIND_ADDRESS
*     <td>null, any available address
*   <tr bgcolor="#eeeeff">
*     <td>Binding Port
*     <td>The port bind to the service
*     <td>com.toc.jndp.service.port
*     <td>KEY_JNDP_PORT
*     <td>1099
*   <tr>
*     <td>Binding RMI Port
*     <td>The port bind to the service for RMI to export the remote object
*     <td>com.toc.jndp.service.rmiport
*     <td>KEY_JNDP_RMI_PORT
*     <td>0, random port
*   <tr bgcolor="#eeeeff">
*     <td>Binding Backlog
*     <td>The maximum queue length for incoming connection
*     <td>com.toc.jndp.service.backlog
*     <td>KEY_JNDP_BACKLOG
*     <td>50
*   <tr>
*     <td>Binding RMI Port
*     <td>The port bind to the service for RMI
*     <td>com.toc.jndp.service.rmiport
*     <td>KEY_JNDP_RMI_PORT
*     <td>0, random port
*   <tr bgcolor="#eeeeff">
*     <td>Server Socket Factory
*     <td>JNDP Server Socket Factory.
*     <td>com.toc.jndp.service.server.socket.factory
*     <td>KEY_JNDP_SERVER_SOCKET_FACTORY
*     <td>javax.net.ServerSocketFactory$DefaultServerSocketFactory
*   <tr>
*     <td>RMI Server Socket Factory
*     <td>JNDP RMI Server Socket Factory, to create the socket for server accept remote call.
*     <td>com.toc.jndp.service.rmi.server.socket.factory
*     <td>KEY_JNDP_RMI_SERVER_SOCKET_FACTORY
*     <td>{@link com.toc.lib.net.DefaultServerSocketFactory}
*   <tr bgcolor="#eeeeff">
*     <td>RMI Client Socket Factory
*     <td>JNDP RMI Client Socket Factory, to create the socket for client to make the call to the server.
*     <td>com.toc.jndp.service.rmi.client.socket.factory
*     <td>KEY_JNDP_RMI_CLIENT_SOCKET_FACTORY
*     <td>null
*   <tr>
*     <td>JNDP Service Provider Storage Implementation Technology
*     <td>The technology of JNDP Service Provider Storage technology, currently support Runtime Hash-Map
*     <td>com.toc.jndp.service.provider.storage.impl
*     <td>KEY_JNDP_STORAGE_IMPLIMENTATION
*     <td>RUNTIME
* </table>
* </blockquote>
* <ul><a name="dependence" /><b>Dependence</b>
* <li>Java 1.6 or later
* <li>TOC Library (toclib.jar)
* <li>TOC Logging (toclog.jar)
* </ul>
* <p>Copyright: Copyright (c) 2010 Thousand Origami Cranes Corp.
* <p>Create Time: Jun 27, 2010 2:01:37 AM
* @author Kevin.Zhou
* @version 1.0
*/
public class JNDService {
  /**
   * The property key of JNDP Binding Address, this property indicate the address bind to the JNDP service.
   */
  public final static String KEY_JNDP_BIND_ADDRESS = "com.toc.jndp.service.bindaddress";
  /**
   * The property key of JNDP Binding Port, this property indicate the socket port bind to the JNDP service.
   */
  public final static String KEY_JNDP_PORT = "com.toc.jndp.service.port";
  /**
   * The property key of JNDP Binding RIM Port, this property indicate the RMI socket port bind to JNDP service.
   */
  public final static String KEY_JNDP_RMI_PORT = "com.toc.jndp.service.rmiport";
  /**
   * The property key of JNDP Backlog, this property indicate the maximum number of incoming connection in queue.
   */
  public final static String KEY_JNDP_BACKLOG = "com.toc.jndp.service.backlog";
  /**
   * The property key of JNDP Server Socket Factory. Default is to use javax.net.ServerSocketFactory$DefaultServerSocketFactory
   */
  public final static String KEY_JNDP_SERVER_SOCKET_FACTORY = "com.toc.jndp.service.server.socket.factory";
  /**
   * The property key of JNDP RMI Server Socket Factory, default is to use com.toc.lib.net.DefaultServerSocketFactory
   */
  public final static String KEY_JNDP_RMI_SERVER_SOCKET_FACTORY = "com.toc.jndp.service.rmi.server.socket.factory";
  /**
   * The property key of JNDP RMI Client SOcket Factory, default is null.
   */
  public final static String KEY_JNDP_RMI_CLIENT_SOCKET_FACTORY = "com.toc.jndp.service.rmi.client.socket.factory";
  /**
   * The property key of JNDP Service Provider Storage Implementation, currently support Runtime Hash-map.
   */
  public final static String KEY_JNDP_STORAGE_IMPLIMENTATION = "com.toc.jndp.service.provider.storage.impl";
 
  /*
   * Store the socket listen to client's connection.
   */
  protected ServerSocket serverSocket;
  /*
   * Store the socket factory to create the JNDP Service Socket.
   */
  protected ServerSocketFactory jndServerSocketFactory;
  /*
   * Store the socket factory for RMI Server to create the socket.
   */
  protected RMIServerSocketFactory serverSocketFactory;
  /*
   * Store the socket factory for RMI Client to create the socket.
   */
  protected RMIClientSocketFactory clientSocketFactory;
  /*
   * Store the Naming service implementation instance
   */
  protected Naming server;
  /*
   * Store the net address binding to the JNDP server, null indicate any available address
   */
  protected InetAddress bindAddress;
  /*
   * Store the maximum size of connection pool, default is 50.
   */
  protected int backlog = 50;
  /*
   * Store the socket port number, default is 1099, 0 indicate any available port.
   */
  protected int port = 1099;
  /*
   * Store the RMI socket port number, the port for server to export the remote object, default is 0 indicate any available port.
   */
  protected int rmiPort = 0;
  /*
   * Store the JNDP provider storage implementation type. 0-RUNTIME
   */
  protected int storageImplType = 0;
  /*
   * Store the RMI Remote object.
   */
  protected MarshalledObject<Remote> serverStub;
 
  /**
   * This method is to start the JNDP Service.
   * <ol>
   * <b>Process</b>
   * <li>Read the jndp.properties to initial the JNDP configuration.
   * <li>Initialize the JNDP Service.
   * <li>Boot up the service listener.
   * </ol>
   * <p>Create Time: Jun 29, 2010 1:46:22 PM
   * <br>Author: kevin.zhou
   * @throws GenericException The exception occur during the service running.
   */
  public void start() throws GenericException {
    try {
      // Read the configurable item from jndp.properties to initial the environment
      initEnvironment();
     
      // Initialize the JNDP Service
      initJNDService();
     
      // Boot up the JNDP Service listener.
      bootJNDPListener();
    } catch(Exception e) {
      throw ExceptionHelper.parse(e);
    }
  }
 
  /**
   * Stop the JNDP Service.
   * <p>Create Time: Jun 29, 2010 1:54:33 PM
   * <br>Author: kevin.zhou
   * @throws GenericException The exception when close the server socket.
   */
  public void stop() throws GenericException {
    try {
      if(serverSocket != null && !serverSocket.isClosed()) {
        serverSocket.close();
      }
      serverSocket = null;
    } catch(Exception e) {
      serverSocket = null;
      throw ExceptionHelper.parse(e);
    }
  }
 
  /**
   * Read the configurable item from jndp.properties, the properties files should put in the class path.
   * <p>Create Time: Jun 29, 2010 2:14:01 PM
   * <br>Author: kevin.zhou
   * @throws GenericException
   */
  protected void initEnvironment() throws GenericException {
    try {
      // Load the jndp.properties file
      Properties prop = new Properties();
      prop.load(ResourceLoader.getClasspathResource("jndp.properties"));
     
      // Load JNDP Binding Address
      String sBindAddress = prop.getProperty(KEY_JNDP_BIND_ADDRESS);
      if(sBindAddress != null && !"".equals(sBindAddress)) {
        try {
          bindAddress = InetAddress.getByName(sBindAddress);
        } catch(Exception e) {
        }
      }
      // Load JNDP Binding Socket Port
      String sPort = prop.getProperty(KEY_JNDP_PORT);
      if(sPort != null && !"".equals(sPort)) {
        try {
          port = Integer.parseInt(sPort);
        } catch(Exception e) {
        }
      }
      // Load JNDP Binding RMI Socket Port
      String sRMIPort = prop.getProperty(KEY_JNDP_RMI_PORT);
      if(sRMIPort != null && !"".equals(sRMIPort)) {
        try {
          rmiPort = Integer.parseInt(sRMIPort);
        } catch(Exception e) {
        }
      }
      // Load JNDP Socket Backlog
      String sBacklog = prop.getProperty(KEY_JNDP_BACKLOG);
      if(sBacklog != null && !"".equals(sBacklog)) {
        try {
          backlog = Integer.parseInt(sBacklog);
        } catch(Exception e) {
        }
      }
      // Load JNDP Service Socket Factory
      String sServerSocketFactory = prop.getProperty(KEY_JNDP_SERVER_SOCKET_FACTORY);
      if(sServerSocketFactory != null && !"".equals(sServerSocketFactory)) {
        try {
          jndServerSocketFactory = (ServerSocketFactory)this.getClass().getClassLoader().loadClass(sServerSocketFactory).newInstance();
        } catch(Exception e) {
        }
      }
      // Load JNDP RMI Server Socket Factory
      String sRMIServerSocketFactory = prop.getProperty(KEY_JNDP_RMI_SERVER_SOCKET_FACTORY);
      if(sRMIServerSocketFactory != null && !"".equals(sRMIServerSocketFactory)) {
        try {
          serverSocketFactory = (RMIServerSocketFactory)this.getClass().getClassLoader().loadClass(sRMIServerSocketFactory).newInstance();
        } catch(Exception e) {
        }
      }
      // Load JNDP RMI Client Socket Factory
      String sRMIClientSocketFactory = prop.getProperty(KEY_JNDP_RMI_CLIENT_SOCKET_FACTORY);
      if(sRMIClientSocketFactory != null && !"".equals(sRMIClientSocketFactory)) {
        try {
          clientSocketFactory = (RMIClientSocketFactory)this.getClass().getClassLoader().loadClass(sRMIClientSocketFactory).newInstance();
        } catch(Exception e) {
        }
      }
      //Load JNDP Provider Implementation Type
      String sProviderImplType = prop.getProperty(KEY_JNDP_STORAGE_IMPLIMENTATION);
      if(sProviderImplType != null && !"".equals(sProviderImplType)) {
        try {
          if(sProviderImplType.equals("RUNTIME")) {
            storageImplType = 0;
          }
        } catch(Exception e) {
        }
      }
    } catch(Exception e) {
      ExceptionHelper.log(e);
    }
  }
 
  /**
   * <ul>Initialize the JNDP Service
   * <li>Initialize the JNDP Service Naming Provider
   * <li>Create the Remote Object of Naming Provider
   * </ul>
   * <p>Create Time: Jun 30, 2010 1:59:46 PM
   * <br>Author: kevin.zhou
   * @throws GenericException Exception when initialize the JNDP Service
   */
  protected void initJNDService() throws GenericException {
    try {
      if(server == null) {
        server = NamingFactory.create(storageImplType);
      }
      if(serverSocketFactory == null) {
        serverSocketFactory = new DefaultServerSocketFactory();
      }
      Remote stub = UnicastRemoteObject.exportObject(server, rmiPort, clientSocketFactory, serverSocketFactory);
      serverStub = new MarshalledObject<Remote>(stub);
    } catch(Exception e) {
      throw ExceptionHelper.parse(e);
    }
  }
 
  /**
   * Boot JNDP Listener up
   * <p>Create Time: Jul 1, 2010 11:15:27 AM
   * <br>Author: kevin.zhou
   */
  protected void bootJNDPListener() throws GenericException {
    try {
      // Check if pointed server socket factory, otherwise use Default server socket factory
      if(jndServerSocketFactory == null) {
        jndServerSocketFactory = ServerSocketFactory.getDefault();
      }
      // Create service socket port
      serverSocket = jndServerSocketFactory.createServerSocket(port, backlog, bindAddress);
      if(port == 0) {
        port = serverSocket.getLocalPort();
      }
     
      // Boot JNDP Listener up
      SocketAcceptHandler jndAccept = new SocketAcceptHandler(this);
      Thread t = new Thread(jndAccept, "JNP Server");
      t.start();
    } catch(Exception e) {
      throw ExceptionHelper.parse(e);
    }
  }
 
  /**
   * Title: Client Call Accepter
   * <p>Description: This class is implements Runnable interface, it will start a thread to listen the client call and pass the client request to request handler.
   * <p>Copyright: Copyright (c) 2010 Thousand Origami Cranes Corp.
   * <p>Create Time: Jul 1, 2010 4:51:23 PM
   * <br>Author: kevin.zhou
   * @version 1.0
   */
  private class SocketAcceptHandler implements Runnable {
    /**
     * A variable to store the JNDP Service instance for recall
     */
    private JNDService service;
   
    /**
     * Structure
     * @param service JNDP Service instance
     */
    public SocketAcceptHandler(JNDService service) {
      this.service = service;
    }
   
    /**
     * Start the thread to accept client call and forward the client request to request handler.
     * <p>Create Time: Jul 1, 2010 5:12:04 PM
     * <br>Author: kevin.zhou
     * @see java.lang.Runnable#run()
     *
     */
    public void run() {
      // Start the loop to accept client call and start a new thread of request handler to process client request.
      while(service.serverSocket != null) {
        Socket socket = null;
        try {
          socket = JNDService.this.serverSocket.accept();
          // Start the thread to handle client request (Deliver remote stub object to client)
          RMIRequestHandler rmiServer = new RMIRequestHandler(service, socket);
          Thread t = new Thread(rmiServer, "JNP Server");
          t.start();
        } catch(Exception e) {
          e.printStackTrace();
        }
      }
    }
  }
 
  /**
   * Title: JNDP Client Request Handler
   * <p>Description: This class is implements Runnable interface, it will start a thread to process client request to deliver the RMI remote stub object via server socket.
   * <p>Copyright: Copyright (c) 2010 Thousand Origami Cranes Corp.
   * <p>Create Time: Jul 1, 2010 5:56:13 PM
   * <br>Author: kevin.zhou
   * @version 1.0
   */
  private class RMIRequestHandler implements Runnable {
    /**
     * Store the Client socket
     */
    private Socket socket;
    /**
     * The JNDP Service instance for get Remote Stub Object
     */
    private JNDService service;
   
    /**
     * Constructor
     * @param service The JNDP Service instance
     * @param socket Client socket
     */
    public RMIRequestHandler(JNDService service, Socket socket) {
      this.service = service;
      this.socket = socket;
    }

    /**
     * Start to process client request, to deliver Service RMI Stub Remote Object ot client
     * <p>Create Time: Jul 2, 2010 11:59:44 AM
     * <br>Author: kevin.zhou
     * @see java.lang.Runnable#run()
     *
     */
    public void run() {
      try {
        OutputStream os = this.socket.getOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(os);
        out.writeObject(service.serverStub);
        out.close();
      } catch(Exception e) {
        e.printStackTrace();
      }
    }
  }
}
TOP

Related Classes of com.toc.jndp.JNDService$SocketAcceptHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.